
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

void help ();

void version();

void mergesort(char* inputs []);

void selsort(char* inputs []);

int main (int argc, char **argv)
{
  int siguiente_opcion;
  void (*cmd) () = NULL;
  void (*cmd_sort) (char* inputs []) = NULL;
    
  /* Una cadena que lista las opciones cortas validas */
  const char* const op_cortas = "hvms" ;

  /* Una estructura de varios arrays describiendo los valores largos */
  const struct option op_largas[] =
  {
      { "help",    0,  NULL,   'h'},
      { "version", 0,  NULL,   'v'},
      { "merge",   0,  NULL,   'm'},
      { "sel",     0,  NULL,   's'},
      { NULL,      0,  NULL,   0  }
  };

  
  if (argc == 1)
  {
      /* Se ejecuta sin parametros ni opciones.  Por default ejecuta help. */  
      help();
      exit(EXIT_SUCCESS);
  }
  
  while (1)
  {
      /* Llamamos a la funcion getopt */
      siguiente_opcion = getopt_long (argc, argv, op_cortas, op_largas, NULL);
    
      if (-1 == siguiente_opcion)
          break; /* No hay mas opciones. Rompemos el bucle */

      switch (siguiente_opcion)
      {
          case 'h' : /* -h o --help */
              cmd = help;
              break;
              
          case 'v' : /* -v o --version */
              cmd = version;
              break;
        
          case 'm' : /* -o --merge */
              cmd_sort = mergesort;
              break;

          case 's' : /* -s --sel */
              cmd_sort = selsort;
              break;
                      
          case '?' : /* opcion no valida */
              cmd = help;
              break;

          default : /* Algo mas No esperado. Abortamos */
              cmd = help;
      }
  }

  /* Leo la lista de nombres de archivo de entrada.*/
  char* inputs [(argc - optind) + 1];
  inputs[0] = NULL;  
  
  if (optind < argc)
  {
      int cur = 0;
      while (optind < argc)
          inputs[cur++] = argv[optind++];
          inputs[cur] = NULL;          
  }  

  if (NULL != cmd_sort)
  {
     /* Se selecciono la opcion merge o sel.  Ejecuto el comando asociado. */   
     cmd_sort(inputs);
  }
  else
    /* Se selecciono la opcion help o version.  ejecuto el comando asociado. */
    cmd();
  
  /* Salida del programa principal */
  return 0;
    
} // main

void help ()
{
    printf("\ntp0 [OPTIONS] [File ...]\n");
    printf("    -h,  --help           display this help and exit.\n"
           "    -v,  --version        display version information and exit.\n"
           "    -m,  --merge          use the mergesort algorithm.\n"
           "    -s,  --sel            use the selectionsort algorithm.\n\n"
          );
} // help

void version()
{
    printf("\n\ntp0 version 4.0\n\n");

} // version

void mergesort(char* inputs []){
    printf ("Mergesort!");   

    int cur = 0;
    while (NULL != inputs [cur])
        printf (" %s ", inputs[cur++]);

} // mergesort

void selsort(char* inputs [])
{
    printf ("Selectionsort!");

    int cur = 0;
    while (NULL != inputs [cur])
        printf (" %s ", inputs[cur++]);

} // selsort
